<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      body {
        margin: 0;
        font-size: 14px;
      }
    </style>
  </head>

  <body>
    <div id="jsContainer">
      <ul class="js-test" id="jsParent">
        <li data-index="0">1</li>
        <li data-index="1">2</li>
      </ul>
      <span style="font-weight: bold">3</span>
      4
    </div>
    <script type="text/javascript">
      /**
       * 页面上存在id=jsContainer的节点A，系统会随机在节点A中生成文档片段，请按照如下需求实现 dom2json 函数
        1、dom2json需要分析整个节点A的dom结构，并将其结构转换为对应的json对象
        2、需要获取dom结构的标签名称(tag)，所有属性(attributes)，子节点(children)
        3、文档片段中的属性形式均为 name="value"，解析之后的格式为{name: value}, 属性值为String类型，不需要做解析
        4、随机生成的文档片段中，只包含 nodeType 为1(element)和3(text)的节点，不需要考虑其他节点类型
        5、纯文本也视为一个节点, json格式为 {tag: 'text', content: '文本内容'}，content为文本内容执行trim后的结果，如果该结果为空，则忽略当前节点
        6、返回结果中的标签名称不区分大小写
        7、如果节点不包含属性值或者子节点，其对应的结果中需要保留attributes以及children字段，例如 {tag: 'div', attributes: {}, children: []}
        8、当前界面执行dom2json之后的结果为如下图所示
        9、请不要手动修改html和css
        10、不要使用第三方插件
      */
      function dom2json() {
        const jsContainer = document.getElementById('jsContainer')
        return createObj(jsContainer)
      }
      function createObj(element) {
        // 创建一个空的对象
        const obj = {}
        // 获得标签名，nodeName 可以获得 text 标签(里面好多回车)，typeName 获得是标签
        obj.tag = element.nodeName.toLowerCase().replace('#', '')
        if (obj.tag == 'text') {
          obj.content = element.data.trim()
        }
        //attributes初始化，如果有，那么逐个添加attributes
        obj.attributes = {}
        if (element.attributes) {
          for (let i = 0; i < element.attributes.length; i++) {
            const { name, value } = element.attributes[i];
            obj.attributes[name] = value;
          }
        }
        // 对孩子数组过滤，去除没有内容的 text
        const childArr = Array.from(element.childNodes).filter((item) => {
          return item.nodeName === '#text' && item.data.trim() !== '' || item.nodeName !== '#text';
        })
        // 4.1如果有孩子，那么递归调用自己，添加第i个数组元素
        obj.children = []
        if (childArr.length) {
          for (let i = 0; i < childArr.length; i++) {
            obj.children[i] = createObj(childArr[i]);
          }
        }
        return obj
      }
      // console.log(dom2json())
    </script>
  </body>
</html>
